package cn.hh.redis.util;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.Security;

public class UopThreeDES {
    //单例
    public static UopThreeDES threeDES = null;

    //UopFeignServiceImpl.class与WebFeignController.class 使用
    // public static final String KEY = "sas998#";

    /**
     * 实例化
     *
     * @return
     */
    public static UopThreeDES getInstance() {
        if (threeDES == null) {
            threeDES = new UopThreeDES();
        }
        return threeDES;
    }

    /**
     *
     */
    public UopThreeDES() {
        Security.addProvider(new com.sun.crypto.provider.SunJCE());
    }

    /**
     * 加密
     *
     * @param src
     * @param key
     * @return
     */
    public String encrypt(String src, String key) {
        return encrypt(src, key.getBytes());
    }

    /**
     * 加密
     *
     * @param src
     * @return
     */
    public String encrypt(String src, byte[] key) {
        if (src == null) {
            return null;
        }
        byte[] encoded = encryptMode(key, src.getBytes());
        return byte2hex(encoded);
    }

    /**
     * 解密
     *
     * @param src
     * @param key
     * @return
     */
    public String decrypt(String src, String key) {
        return decrypt(src, key.getBytes());
    }

    /**
     * 加密 用于url参数  无特殊字符
     *
     * @param src
     * @param key
     * @return
     */
/*    public String encryptEncode(String src, String key) {
        String KEY_3DES = UopMD5Utils.encryptByMD5(key).substring(0, 24);
        return encrypt(src, KEY_3DES.getBytes());
    }*/

    /**
     * 解密 用于encryptToP
     *
     * @param src
     * @param key
     * @return
     */
/*    public String decryptEncode(String src, String key) {
        String KEY_3DES = UopMD5Utils.encryptByMD5(key).substring(0, 24);
        return decrypt(src, KEY_3DES.getBytes());
    }*/

    /**
     * 解密
     *
     * @param src
     * @return
     */
    public String decrypt(String src, byte[] key) {
        if (src == null) {
            return null;
        }
        byte[] b = hex2byte(src);
        byte[] srcBytes = decryptMode(key, b);
        String rs = null;
        try {
            rs = new String(srcBytes, "utf-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return rs;
    }

    //定义 加密算法,可用 DES,DESede,Blowfish
    private static final String Algorithm = "DESede";

    /**
     * 3DES	加密
     *
     * @param keybyte
     * @param src
     * @return
     */
    private byte[] encryptMode(byte[] keybyte, byte[] src) {
        try {
            //生成密钥
            SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);
            //加密
            Cipher c1 = Cipher.getInstance(Algorithm);
            c1.init(Cipher.ENCRYPT_MODE, deskey);
            return c1.doFinal(src);
        } catch (java.security.NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        } catch (javax.crypto.NoSuchPaddingException e2) {
            e2.printStackTrace();
        } catch (java.lang.Exception e3) {
            e3.printStackTrace();
        }
        return null;
    }

    /**
     * 3DES 解密
     *
     * @param keybyte
     * @param src
     * @return
     */
    private byte[] decryptMode(byte[] keybyte, byte[] src) {
        try {
            //生成密钥
            SecretKey deskey = new SecretKeySpec(keybyte, Algorithm);

            //解密
            Cipher c1 = Cipher.getInstance(Algorithm);
            c1.init(Cipher.DECRYPT_MODE, deskey);
            return c1.doFinal(src);
        } catch (java.security.NoSuchAlgorithmException e1) {
            e1.printStackTrace();
        } catch (javax.crypto.NoSuchPaddingException e2) {
            e2.printStackTrace();
        } catch (java.lang.Exception e3) {
            e3.printStackTrace();
        }
        return null;
    }

    /**
     * 转换成十六进制字符串
     *
     * @param b
     * @return
     */
    private String byte2hex(byte[] b) {
        String hs = "";
        String stmp = "";
        for (int n = 0; n < b.length; n++) {
            stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
            if (stmp.length() == 1) {
                hs = hs + "0" + stmp;
            } else {
                hs = hs + stmp;
            }
        }
        return hs.toUpperCase();
    }

    /**
     * 将十六进制字符串转化为字符数组
     *
     * @param hexStr
     * @return
     */
    private byte[] hex2byte(String hexStr) {
        byte[] b = new byte[hexStr.length() / 2];
        int j = 0;
        char c0 = 0;
        char c1 = 0;
        for (int i = 0; i < b.length; i++) {
            c0 = hexStr.charAt(j);
            j++;
            c1 = hexStr.charAt(j);
            j++;
            b[i] = (byte) ((parse(c0) << 4) | (parse(c1)));
        }
        return b;
    }

    /**
     * 将字符转化为字节值
     *
     * @param c
     * @return
     */
    private int parse(char c) {
        if (c >= 'A' && c <= 'F') {
            return (c - 'A' + 10) & 0x0f;
        } else if (c >= 'a' && c <= 'f') {
            return (c - 'a' + 10) & 0x0f;
        } else {
            return (c - '0') & 0x0f;
        }
    }

    public static void main(String[] args) {
        /*String ward = UopThreeDES.getInstance().encryptEncode("tel", "wwwwwwww");
        String deward = UopThreeDES.getInstance().decryptEncode(ward, "wwwwwwww");
        System.out.println(ward);
        System.out.println(deward);*/
    }
}

